package com.jweb.framework.core.service;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import com.jweb.framework.core.CoreRuntimeException;
import com.jweb.framework.core.listener.ServiceRegistryListener;
import com.jweb.framework.core.support.TRACER;
/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明： 默认服务注册
 */
public class DefaultServiceRegistry extends ServiceRegistryListener implements ServiceRegistry , DisposableBean , InitializingBean {
	
	private ConcurrentHashMap<Object, Object> services = new ConcurrentHashMap<Object, Object>();
	private boolean throwExceptionIfNotFound = true ;
	private boolean throwExceptionIfDuplicated = true ;
	
	public void setThrowExceptionIfNotFound(boolean throwExceptionIfNotFound) {
		this.throwExceptionIfNotFound = throwExceptionIfNotFound;
	}

	public void setThrowExceptionIfDuplicated(boolean throwExceptionIfDuplicated) {
		this.throwExceptionIfDuplicated = throwExceptionIfDuplicated;
	}
	
	/**
	 * findService(Class<T> clazz)此方法被用于DefaultContext为，即被放到上下文Context中，这样整个随时可以
	 * 		从Context中取出自己注入的服务并使用。
	 */
	public <T> T findService(Class<T> clazz) {
		
		Object obj = this.services.get(clazz);
		if(obj==null && this.throwExceptionIfNotFound){
			throw new CoreRuntimeException("JAVACO0020" , new String[]{clazz.getName()} , "no_service_found");
		}
		return (T) obj ;
	}

	public <T> T findService(String s) {
		
		Object obj = this.services.get(s);
		if(obj==null && this.throwExceptionIfNotFound){
			throw new CoreRuntimeException("JAVACO0021" , new String[]{s} , "no_service_found");
		}
		return (T) obj ;
	}

	public void register(ServiceHolder serviceHolder) {
		
		Object obj1 ;
		if(serviceHolder.getName() != null){
			obj1 = this.services.putIfAbsent(serviceHolder.getName(), serviceHolder.getService());
			if(this.throwExceptionIfDuplicated && obj1!=null){
				throw new CoreRuntimeException("JAVACO0022" , new String[]{serviceHolder.getName()} , "duplicated_service_defined");
			}
			TRACER.trace("register service , name: {}" , new String[]{serviceHolder.getName()});
		}
		else {
			for(Class<?> clazz : serviceHolder.getTypes()){
				Object obj2 = this.services.putIfAbsent(clazz, serviceHolder.getService());
				if(this.throwExceptionIfDuplicated && obj2 != null){
					throw new CoreRuntimeException("JAVACO0023" , new String[]{clazz.getName()} , "duplicated_service_defined");
				}
				TRACER.trace("register service , type : {}" , new String[]{clazz.getName()});
			}
		}
	}

	public void unregister(ServiceHolder serviceHolder) {
		
		if(serviceHolder.getName()!=null){
			if(this.services.remove(serviceHolder.getName())!=null){
				TRACER.trace("unregister service , name: {}" , new String[]{serviceHolder.getName()});
			}
		}
		else{
			for(Class<?> clazz : serviceHolder.getTypes()){
				if(this.services.remove(clazz)!=null){
					TRACER.trace("unregister service , type: {}" , new String[]{clazz.getName()});
				}
			}
		}
	}

	public void destroy() throws Exception {
		unbind(this , null);
	}

	public void afterPropertiesSet() throws Exception {
		bind(this , null);
	}

}
